﻿using System.Collections.Generic;
using System.Linq;
using Fabrication.Tests.TestClasses;
using NUnit.Framework;

namespace Fabrication.Tests
{
    [TestFixture]
    public class numeric_rules
    {
        [Test]
        public void should_set_range_for_integer_properties()
        {
            var builtItem = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.IntValue).UseRange(1000, 2000)
                .Generate();

            Assert.That(builtItem.IntValue, Is.InRange(1000, 2000));
        }

        [Test]
        public void should_set_range_for_long_properties()
        {
            var builtItem = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.LongValue).UseRange(1000, 2000)
                .Generate();

            Assert.That(builtItem.LongValue, Is.InRange(1000, 2000));
        }

        [Test]
        public void should_set_range_for_float_properties()
        {
            var builtItem = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.FloatValue).UseRange(1000, 2000)
                .Generate();

            Assert.That(builtItem.FloatValue, Is.InRange(1000, 2000));
        }

        [Test]
        public void should_set_range_for_double_properties()
        {
            var builtItem = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.DoubleValue).UseRange(1000, 2000)
                .Generate();

            Assert.That(builtItem.DoubleValue, Is.InRange(1000, 2000));
        }

        [Test]
        public void should_set_range_for_decimal_properties()
        {
            var builtItem = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.DecimalValue).UseRange(1000, 2000)
                .Generate();

            Assert.That(builtItem.DecimalValue, Is.InRange(1000, 2000));
        }

        [Test]
        public void should_set_range_sequence_for_integer_properties()
        {
            var builtItems = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.IntValue).UseSequence(5, 8)
                .Generate(5);

            var actual = builtItems.Select(b => b.IntValue).ToList();
            var expected = new List<int> { 5, 6, 7, 8, 5 };

            Assert.That(actual, Is.EquivalentTo(expected));
        }

        [Test]
        public void should_set_range_sequence_for_long_properties()
        {
            var builtItems = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.LongValue).UseSequence(5, 8)
                .Generate(5);

            var actual = builtItems.Select(b => b.LongValue).ToList();
            var expected = new List<int> { 5, 6, 7, 8, 5 };

            Assert.That(actual, Is.EquivalentTo(expected));
        }

        [Test]
        public void should_set_range_sequence_for_decreasing_integer_range()
        {
            var builtItems = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.IntValue).UseSequence(2, -1)
                .Generate(5);

            var actual = builtItems.Select(b => b.IntValue).ToList();
            var expected = new List<int> { 2, 1, 0, -1, 2 };

            Assert.That(actual, Is.EquivalentTo(expected));
        }

        [Test]
        public void should_set_range_sequence_for_decreasing_long_range()
        {
            var builtItems = new FabricationScope().Setup<NumericsOnly>()
                .For(x => x.LongValue).UseSequence(2, -1)
                .Generate(5);

            var actual = builtItems.Select(b => b.LongValue).ToList();
            var expected = new List<int> { 2, 1, 0, -1, 2 };

            Assert.That(actual, Is.EquivalentTo(expected));
        }

        [Test]
        public void should_set_zip_code_by_convention()
        {
            var builtItem = new FabricationScope().Generate<PostCodesConventionClass>();

            Assert.That(builtItem.Zip, Is.InRange(10000, 99999));
            Assert.That(builtItem.ZipCode, Is.InRange(10000, 99999));
            Assert.That(builtItem.PostCode, Is.InRange(10000, 99999));
        }

        [Test]
        public void should_set_zip_code_by_rule()
        {
            var builtItem = new FabricationScope().Setup<SinglePropertyClass<int>>()
                .For(x => x.Value).GeneratePostCode()
                .Generate();

            Assert.That(builtItem.Value, Is.InRange(10000, 99999));
        }
    }
}